﻿using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Macds.Core.IoC;
using Macds.Test.Core.IoC.Mocks;

namespace Macds.Test.Core.IoC
{
    /// <summary>
    /// Summary description for DependencyFactoryTest
    /// </summary>
    [DeploymentItem("C:\\Codeplex\\macds\\development\\source\\Macds.Test\\services.config")]
    [DeploymentItem("C:\\Codeplex\\macds\\development\\source\\Macds.Test\\items.config")]
    [DeploymentItem("C:\\Codeplex\\macds\\development\\source\\Macds.Test\\values.config")]
    [DeploymentItem("C:\\Codeplex\\macds\\development\\source\\Macds.Test\\modelConfigurations.config")]
    [DeploymentItem("C:\\Codeplex\\macds\\development\\source\\Macds.Test\\IoC.config")]
    [TestClass]
    public class DependencyFactoryTest
    {
        public DependencyFactoryTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void LoadItemsWithoutSectionGroup()
        {
            DependencyFactory ioc = new DependencyFactory();
            var service1 = ioc.Create<Service>("Service1");
        }

        [TestMethod]
        public void CreateObjectWithListpropertyWithDefaultValues()
        {
            DependencyFactory ioc = new DependencyFactory(true);
            var values = ioc.Create<DefaultValues>("DefaultValues");
        }
        
        [TestMethod]
        public void CreateObjectWithDefaultProperties()
        {
            DependencyFactory ioc = new DependencyFactory(true);
            var item = ioc.Create<IInterface>("Item1");

            Assert.AreEqual("ItemOne", item.Name);
            Assert.AreEqual(1, item.Value);
            Assert.AreEqual("One", item.Process());
        }

        [TestMethod]
        public void CreateObjectWithDefaultPropertiesAndObjectInstance()
        {
            DependencyFactory ioc = new DependencyFactory(true);
            var item = ioc.Create<IInterface>("Item2");
            ItemTwo obj = (ItemTwo)item;

            Assert.AreEqual("Two", item.Process());
            Assert.IsNotNull(obj.Internal);
            Assert.AreEqual("Internal", obj.Internal.Name);
        }

        [TestMethod]
        public void CreateObjectWithListOfItems()
        {
            DependencyFactory ioc = new DependencyFactory(true);
            var item = ioc.Create<Service>("Service1");

            Assert.AreEqual("ItemOne", item.Items[0].Name);
            Assert.AreEqual(1, item.Items[0].Value);
            Assert.AreEqual("One", item.Items[0].Process());

            ItemTwo obj = (ItemTwo)item.Items[1];
            Assert.AreEqual("Two", item.Items[1].Process());
            Assert.IsNotNull(obj.Internal);
            Assert.AreEqual("Internal", obj.Internal.Name);

            Assert.AreEqual("Tree", item.Items[2].Process());
        }

        [TestMethod]
        public void CreateObjectWithDefaultPropertiesWithCacheEnabled()
        {
            DependencyFactory ioc = new DependencyFactory(true);
            var item1 = ioc.Create<IInterface>("Item1");

            Assert.AreEqual("ItemOne", item1.Name);
            Assert.AreEqual(1, item1.Value);
            Assert.AreEqual("One", item1.Process());

            var item2 = ioc.Create<IInterface>("Item1");

            Assert.AreEqual("ItemOne", item2.Name);
            Assert.AreEqual(1, item2.Value);
            Assert.AreEqual("One", item2.Process());
        }

        [TestMethod]
        public void LoadCustomConfigObjectTest()
        {
            DependencyFactory ioc = new DependencyFactory(true);
            var config = ioc.Create<IConfiguration>("CustomConfigModel");

            Assert.AreEqual("www.google1.com", config.UrlAPI1);
            Assert.AreEqual("www.google2.com", config.UrlAPI2);
            Assert.AreEqual("www.google3.com", config.UrlAPI3);
            Assert.AreEqual("www.google4.com", config.UrlAPI4);
        }

        [TestMethod]
        public void LoadObjectWithConstructorParameterAsValueFirm1Test()
        {
            DependencyFactory ioc = new DependencyFactory();
            var person1 = ioc.Create<Person>("Person1");

            Assert.IsTrue(person1.Name == "Person1");
        }

        [TestMethod]
        public void LoadObjectWithConstructorParameterAsValueFirm2Test()
        {
            DependencyFactory ioc = new DependencyFactory();
            var person2 = ioc.Create<Person>("Person2");

            Assert.IsTrue(person2.Name == "Person2");
            Assert.IsTrue(person2.LastName == "LastName2");
        }

        [TestMethod]
        public void LoadObjectWithConstructorParameterAsObjectFirm1Test()
        {
            DependencyFactory ioc = new DependencyFactory();
            var family1 = ioc.Create<Family>("Family1");

            Assert.IsTrue(family1.Father.Name == "Person1");
        }

        [TestMethod]
        public void LoadObjectWithConstructorParameterAsObjectFirm2Test()
        {
            DependencyFactory ioc = new DependencyFactory();
            var family2 = ioc.Create<Family>("Family2");

            Assert.IsTrue(family2.Father.Name == "Person1");
            Assert.IsTrue(family2.Mother.Name == "Person2");
            Assert.IsTrue(family2.Mother.LastName == "LastName2");
        }
    }
}
